// 性能优化工具类
// 实现各种性能优化功能，如防抖、节流、内存管理等

import { performanceConfig } from '../config/performanceConfig';

// 获取性能配置
const getConfig = () => {
  const { rendering, memory } = performanceConfig;
  return { rendering, memory };
};

/**
 * 防抖函数 - 延迟执行函数，直到用户停止触发事件
 * @param {Function} func - 要执行的函数
 * @param {number} wait - 等待时间（毫秒）
 * @param {Object} options - 配置选项
 * @returns {Function} 防抖后的函数
 */
export const debounce = (func, wait = null, options = {}) => {
  // 使用默认配置或传入的配置
  const defaultWait = getConfig().rendering.defaultDebounceDelay;
  const delay = wait !== null ? wait : defaultWait;
  
  let timeoutId = null;
  let lastArgs = null;
  let lastThis = null;
  let lastCallTime = null;
  
  // 配置选项
  const { leading = false, trailing = true, maxWait = null } = options;
  let lastInvokeTime = 0;
  
  // 执行函数
  const invokeFunc = (time) => {
    const args = lastArgs;
    const thisArg = lastThis;
    
    lastArgs = null;
    lastThis = null;
    lastInvokeTime = time;
    
    return func.apply(thisArg, args);
  };
  
  // 启动定时器
  const startTimer = (pendingFunc, wait) => {
    return setTimeout(pendingFunc, wait);
  };
  
  // 取消定时器
  const cancelTimer = (id) => {
    clearTimeout(id);
  };
  
  // 计算剩余等待时间
  const remainingWait = (time) => {
    const timeSinceLastCall = time - lastCallTime;
    const timeSinceLastInvoke = time - lastInvokeTime;
    const timeWaiting = delay - timeSinceLastCall;
    
    return maxWait !== null ? Math.min(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting;
  };
  
  // 判断是否应该在开始时调用
  const shouldInvoke = (time) => {
    const timeSinceLastCall = time - lastCallTime;
    const timeSinceLastInvoke = time - lastInvokeTime;
    
    // 首次调用、调用间隔超过等待时间、调用间隔超过最大等待时间
    return (
      lastCallTime === null ||
      timeSinceLastCall >= delay ||
      timeSinceLastCall < 0 ||
      (maxWait !== null && timeSinceLastInvoke >= maxWait)
    );
  };
  
  // 领先调用函数
  const leadingEdge = (time) => {
    lastInvokeTime = time;
    startTimer(timerExpired, delay);
    return leading ? invokeFunc(time) : undefined;
  };
  
  // 定时器到期处理
  const timerExpired = () => {
    const time = Date.now();
    if (shouldInvoke(time)) {
      return trailingEdge(time);
    }
    
    // 设置下一个定时器
    const remaining = remainingWait(time);
    timeoutId = startTimer(timerExpired, remaining);
  };
  
  // 尾随调用函数
  const trailingEdge = (time) => {
    timeoutId = null;
    
    if (trailing && lastArgs !== null) {
      return invokeFunc(time);
    }
    
    lastArgs = null;
    lastThis = null;
  };
  
  // 取消防抖
  const cancel = () => {
    if (timeoutId !== null) {
      cancelTimer(timeoutId);
    }
    
    lastCallTime = null;
    lastArgs = null;
    lastThis = null;
    lastInvokeTime = 0;
    timeoutId = null;
  };
  
  // 立即执行
  const flush = () => {
    if (timeoutId !== null) {
      const time = Date.now();
      trailingEdge(time);
    }
    
    return lastArgs !== null ? invokeFunc(Date.now()) : undefined;
  };
  
  // 防抖函数主体
  const debounced = function(...args) {
    const time = Date.now();
    const isInvoking = shouldInvoke(time);
    
    lastArgs = args;
    lastThis = this;
    lastCallTime = time;
    
    if (isInvoking) {
      if (timeoutId === null) {
        return leadingEdge(lastCallTime);
      }
      
      if (maxWait !== null) {
        // 重置定时器
        timeoutId = startTimer(timerExpired, delay);
        return invokeFunc(lastCallTime);
      }
    }
    
    if (timeoutId === null) {
      timeoutId = startTimer(timerExpired, delay);
    }
  };
  
  // 添加辅助方法
  debounced.cancel = cancel;
  debounced.flush = flush;
  
  return debounced;
};

/**
 * 节流函数 - 限制函数在一定时间内最多执行一次
 * @param {Function} func - 要执行的函数
 * @param {number} wait - 等待时间（毫秒）
 * @param {Object} options - 配置选项
 * @returns {Function} 节流后的函数
 */
export const throttle = (func, wait = null, options = {}) => {
  // 使用默认配置或传入的配置
  const defaultWait = getConfig().rendering.defaultThrottleDelay;
  const delay = wait !== null ? wait : defaultWait;
  
  let timeoutId = null;
  let lastArgs = null;
  let lastThis = null;
  let lastInvokeTime = 0;
  
  // 配置选项
  const { leading = true, trailing = true } = options;
  
  // 执行函数
  const invokeFunc = (time) => {
    const args = lastArgs;
    const thisArg = lastThis;
    
    lastArgs = null;
    lastThis = null;
    lastInvokeTime = time;
    
    return func.apply(thisArg, args);
  };
  
  // 启动定时器
  const startTimer = (pendingFunc, wait) => {
    return setTimeout(pendingFunc, wait);
  };
  
  // 取消定时器
  const cancelTimer = (id) => {
    clearTimeout(id);
  };
  
  // 计算剩余等待时间
  const remainingWait = (time) => {
    const timeSinceLastInvoke = time - lastInvokeTime;
    const timeRemaining = delay - timeSinceLastInvoke;
    
    return timeRemaining;
  };
  
  // 领先调用函数
  const leadingEdge = (time) => {
    lastInvokeTime = time;
    return leading ? invokeFunc(time) : undefined;
  };
  
  // 定时器到期处理
  const timerExpired = () => {
    const time = Date.now();
    
    if (lastArgs !== null && trailing) {
      invokeFunc(time);
    }
    
    lastArgs = null;
    timeoutId = null;
    lastInvokeTime = time;
  };
  
  // 执行节流
  const trailingEdge = (time) => {
    timeoutId = null;
    
    if (lastArgs !== null) {
      return invokeFunc(time);
    }
    
    lastArgs = null;
    lastThis = null;
  };
  
  // 取消节流
  const cancel = () => {
    if (timeoutId !== null) {
      cancelTimer(timeoutId);
    }
    
    lastArgs = null;
    lastThis = null;
    lastInvokeTime = 0;
    timeoutId = null;
  };
  
  // 立即执行
  const flush = () => {
    if (timeoutId !== null) {
      cancelTimer(timeoutId);
      timeoutId = null;
    }
    
    return invokeFunc(Date.now());
  };
  
  // 节流函数主体
  const throttled = function(...args) {
    const time = Date.now();
    const timeSinceLastInvoke = time - lastInvokeTime;
    
    lastArgs = args;
    lastThis = this;
    
    // 如果超过等待时间
    if (timeSinceLastInvoke >= delay) {
      if (timeoutId !== null) {
        cancelTimer(timeoutId);
        timeoutId = null;
      }
      
      return leadingEdge(time);
    }
    
    // 如果没有定时器，创建一个
    if (timeoutId === null) {
      timeoutId = startTimer(timerExpired, delay - timeSinceLastInvoke);
    }
  };
  
  // 添加辅助方法
  throttled.cancel = cancel;
  throttled.flush = flush;
  
  return throttled;
};

/**
 * 记忆化函数 - 缓存函数调用结果
 * @param {Function} func - 要记忆化的函数
 * @param {Function} resolver - 缓存键生成函数
 * @returns {Function} 记忆化后的函数
 */
export const memoize = (func, resolver = null) => {
  const cache = new Map();
  const memoized = function(...args) {
    const key = resolver ? resolver.apply(this, args) : JSON.stringify(args);
    
    if (cache.has(key)) {
      return cache.get(key);
    }
    
    const result = func.apply(this, args);
    cache.set(key, result);
    
    return result;
  };
  
  // 清除缓存
  memoized.clear = () => {
    cache.clear();
  };
  
  // 获取缓存大小
  memoized.size = () => {
    return cache.size;
  };
  
  return memoized;
};

/**
 * 性能监控器
 */
export const performanceMonitor = {
  // 开始监控
  start: (name) => {
    if (performanceConfig.debugging.performanceMarks) {
      performance.mark(`${name}-start`);
    }
  },
  
  // 结束监控
  end: (name) => {
    if (performanceConfig.debugging.performanceMarks) {
      performance.mark(`${name}-end`);
      performance.measure(name, `${name}-start`, `${name}-end`);
      
      const measures = performance.getEntriesByName(name);
      if (measures.length > 0) {
        const measure = measures[0];
        
        if (performanceConfig.debugging.consoleMetrics) {
          console.log(`${name}: ${measure.duration.toFixed(2)}ms`);
        }
        
        // 清理性能标记
        performance.clearMarks(`${name}-start`);
        performance.clearMarks(`${name}-end`);
        performance.clearMeasures(name);
        
        return measure.duration;
      }
    }
    
    return 0;
  },
  
  // 获取FPS
  getFPS: () => {
    let frames = 0;
    let lastTime = performance.now();
    
    const updateFPS = () => {
      frames++;
      const currentTime = performance.now();
      
      if (currentTime - lastTime >= 1000) {
        const fps = Math.round((frames * 1000) / (currentTime - lastTime));
        
        // 检查FPS是否低于阈值
        if (fps < performanceConfig.monitoring.thresholds.fps) {
          if (performanceConfig.debugging.consoleMetrics) {
            console.warn(`低FPS警告: ${fps} FPS (阈值: ${performanceConfig.monitoring.thresholds.fps} FPS)`);
          }
        }
        
        frames = 0;
        lastTime = currentTime;
      }
      
      requestAnimationFrame(updateFPS);
    };
    
    updateFPS();
  },
  
  // 监控内存使用
  monitorMemory: () => {
    if (!performanceConfig.memory.enabled) return;
    
    const checkMemory = () => {
      if (navigator.deviceMemory) {
        const totalMemory = navigator.deviceMemory * 1024; // 转换为MB
        const memoryUsed = performance.memory ? performance.memory.usedJSHeapSize / 1048576 : 0; // 转换为MB
        
        // 检查内存使用
        if (memoryUsed > performanceConfig.monitoring.thresholds.memory) {
          if (performanceConfig.debugging.consoleMetrics) {
            console.warn(`内存使用警告: ${memoryUsed.toFixed(2)}MB (阈值: ${performanceConfig.monitoring.thresholds.memory}MB)`);
          }
          
          // 触发内存清理
          memoryManager.cleanup();
        }
        
        // 严重内存压力
        if (memoryUsed > performanceConfig.memory.severePressureThreshold) {
          if (performanceConfig.debugging.consoleMetrics) {
            console.error(`严重内存压力: ${memoryUsed.toFixed(2)}MB`);
          }
          
          // 执行紧急清理
          memoryManager.emergencyCleanup();
        }
      }
    };
    
    // 定期检查
    setInterval(checkMemory, performanceConfig.memory.cleanupInterval);
  }
};

/**
 * 内存管理器
 */
export const memoryManager = {
  // 存储需要清理的对象引用
  objectsToClean: new Map(),
  
  // 存储事件监听器引用
  eventListeners: new Map(),
  
  // 注册对象进行清理
  registerObject: (id, object) => {
    memoryManager.objectsToClean.set(id, object);
  },
  
  // 注销对象
  unregisterObject: (id) => {
    memoryManager.objectsToClean.delete(id);
  },
  
  // 注册事件监听器
  registerEventListener: (element, event, handler) => {
    const key = `${element}-${event}`;
    memoryManager.eventListeners.set(key, { element, event, handler });
  },
  
  // 清理对象
  cleanup: () => {
    const { cleanupStrategies } = performanceConfig.memory;
    
    if (cleanupStrategies.largeObjects) {
      // 清理大型对象
      memoryManager.cleanupLargeObjects();
    }
    
    if (cleanupStrategies.unusedListeners) {
      // 清理未使用的事件监听器
      memoryManager.cleanupEventListeners();
    }
    
    if (cleanupStrategies.domReferences) {
      // 清理DOM引用
      memoryManager.cleanupDomReferences();
    }
  },
  
  // 清理大型对象
  cleanupLargeObjects: () => {
    // 遍历并清理不需要的大型对象
    memoryManager.objectsToClean.forEach((object, id) => {
      // 检查对象是否仍然需要
      if (!memoryManager.isObjectNeeded(object)) {
        // 将对象设置为null，帮助垃圾回收
        object = null;
        memoryManager.objectsToClean.delete(id);
      }
    });
  },
  
  // 清理事件监听器
  cleanupEventListeners: () => {
    // 遍历并移除不再需要的事件监听器
    memoryManager.eventListeners.forEach(({ element, event, handler }, key) => {
      // 检查元素是否仍然在DOM中
      if (!document.body.contains(element)) {
        try {
          element.removeEventListener(event, handler);
        } catch (e) {
          console.warn('移除事件监听器失败:', e);
        }
        
        memoryManager.eventListeners.delete(key);
      }
    });
  },
  
  // 清理DOM引用
  cleanupDomReferences: () => {
    // 这里可以实现清理DOM引用的逻辑
    // 例如：清理不再在DOM中的元素引用
  },
  
  // 检查对象是否仍然需要
  isObjectNeeded: (object) => {
    // 实现判断逻辑，这里简单返回false表示需要清理
    // 实际应用中需要根据业务逻辑判断
    return false;
  },
  
  // 紧急清理
  emergencyCleanup: () => {
    // 清理所有注册的对象
    memoryManager.objectsToClean.clear();
    
    // 移除所有注册的事件监听器
    memoryManager.eventListeners.forEach(({ element, event, handler }) => {
      try {
        element.removeEventListener(event, handler);
      } catch (e) {
        console.warn('紧急清理时移除事件监听器失败:', e);
      }
    });
    
    memoryManager.eventListeners.clear();
    
    // 强制垃圾回收（如果支持）
    if (window.gc) {
      try {
        window.gc();
      } catch (e) {
        console.warn('无法执行垃圾回收:', e);
      }
    }
  }
};

/**
 * 资源加载优化器
 */
export const resourceOptimizer = {
  // 图片懒加载
  lazyLoadImages: (selector = 'img[data-src]') => {
    if (!performanceConfig.resources.images.lazyLoading) return;
    
    const images = document.querySelectorAll(selector);
    const imageObserver = new IntersectionObserver((entries, observer) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          const img = entry.target;
          const src = img.getAttribute('data-src');
          
          if (src) {
            img.src = src;
            img.removeAttribute('data-src');
          }
          
          observer.unobserve(img);
        }
      });
    });
    
    images.forEach(img => {
      imageObserver.observe(img);
    });
  },
  
  // 预加载资源
  preloadResources: (resources = []) => {
    if (!performanceConfig.resources.preload.enabled) return;
    
    resources.forEach(resource => {
      const link = document.createElement('link');
      link.rel = 'preload';
      link.href = resource.url;
      link.as = resource.type;
      
      if (resource.crossorigin) {
        link.crossOrigin = resource.crossorigin;
      }
      
      document.head.appendChild(link);
    });
  },
  
  // 延迟加载脚本
  lazyLoadScript: (url, callback = null) => {
    return new Promise((resolve, reject) => {
      const script = document.createElement('script');
      script.src = url;
      script.async = true;
      
      if (callback) {
        script.onload = callback;
      }
      
      script.onload = () => {
        resolve(script);
        if (callback) callback(script);
      };
      
      script.onerror = () => {
        reject(new Error(`加载脚本失败: ${url}`));
      };
      
      document.body.appendChild(script);
    });
  },
  
  // 优化字体加载
  optimizeFontLoading: () => {
    const { fonts } = performanceConfig.resources;
    
    if (fonts.preloadFonts.length > 0) {
      fonts.preloadFonts.forEach(font => {
        const link = document.createElement('link');
        link.rel = 'preload';
        link.href = font.url;
        link.as = 'font';
        link.type = font.type || 'font/woff2';
        link.crossOrigin = font.crossorigin || 'anonymous';
        
        document.head.appendChild(link);
      });
    }
  }
};

/**
 * 虚拟列表优化器
 */
export const virtualListOptimizer = {
  // 创建虚拟列表
  createVirtualList: (container, items, options = {}) => {
    const { 
      itemHeight = 50, 
      bufferSize = 5,
      renderItem = null,
      onUpdate = null
    } = options;
    
    let startIndex = 0;
    let endIndex = 0;
    let containerHeight = 0;
    let visibleCount = 0;
    
    // 更新虚拟列表
    const updateVirtualList = () => {
      const scrollTop = container.scrollTop;
      const scrollLeft = container.scrollLeft;
      
      // 计算可见项的起始和结束索引
      startIndex = Math.floor(scrollTop / itemHeight) - bufferSize;
      startIndex = Math.max(0, startIndex);
      
      endIndex = startIndex + visibleCount + bufferSize * 2;
      endIndex = Math.min(items.length - 1, endIndex);
      
      // 获取可见项
      const visibleItems = items.slice(startIndex, endIndex + 1);
      
      // 清空容器
      container.innerHTML = '';
      
      // 计算容器总高度
      const totalHeight = items.length * itemHeight;
      container.style.height = `${totalHeight}px`;
      
      // 渲染可见项
      visibleItems.forEach((item, index) => {
        const actualIndex = startIndex + index;
        const itemElement = renderItem(item, actualIndex);
        
        if (itemElement) {
          // 设置样式
          itemElement.style.position = 'absolute';
          itemElement.style.top = `${actualIndex * itemHeight}px`;
          itemElement.style.height = `${itemHeight}px`;
          itemElement.style.width = '100%';
          
          container.appendChild(itemElement);
        }
      });
      
      // 触发更新回调
      if (onUpdate) {
        onUpdate({
          startIndex,
          endIndex,
          visibleItems
        });
      }
    };
    
    // 初始化
    const init = () => {
      containerHeight = container.clientHeight;
      visibleCount = Math.ceil(containerHeight / itemHeight);
      
      // 设置容器样式
      container.style.position = 'relative';
      container.style.overflow = 'auto';
      container.style.height = containerHeight + 'px';
      
      // 添加滚动事件监听
      container.addEventListener('scroll', debounce(updateVirtualList, 16));
      
      // 初始化渲染
      updateVirtualList();
    };
    
    // 销毁虚拟列表
    const destroy = () => {
      container.removeEventListener('scroll', updateVirtualList);
    };
    
    // 更新数据
    const updateItems = (newItems) => {
      items = newItems;
      updateVirtualList();
    };
    
    // 初始化
    init();
    
    return {
      update: updateVirtualList,
      destroy,
      updateItems
    };
  }
};

/**
 * 导出性能工具对象
export const performanceUtils = {
  debounce,
  throttle,
  memoize,
  monitor: performanceMonitor,
  memory: memoryManager,
  resource: resourceOptimizer,
  virtualList: virtualListOptimizer,
  getConfig
};*/

// 导出性能工具对象
export default {
  debounce,
  throttle,
  memoize,
  monitor: performanceMonitor,
  memory: memoryManager,
  resource: resourceOptimizer,
  virtualList: virtualListOptimizer,
  getConfig
};